package com.hj.response.exception;

import cn.hutool.core.exceptions.ValidateException;
import com.hj.exception.HjException;
import com.hj.exception.SysException;
import com.hj.i18n.ResourcesI18n;
import com.hj.response.resp.RestfulResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @author hj
 * @Date 2023/4/26
 * @Description: 全局异常处理
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(HjException.class)
    public RestfulResult<SysException> handlerHjException(HjException e) {
        String errMsg = e.getMessage();
        log.warn("HjException--异常:{}", errMsg);
        String message = ResourcesI18n.getMessage(errMsg);
        return RestfulResult.fail(e.getCode(), message);
    }

    @ExceptionHandler(SysException.class)
    public RestfulResult<SysException> handlerSysException(SysException e) {
        String errMsg = e.getMessage();
        log.warn("SysException--异常:{}", errMsg);
        String message = ResourcesI18n.getMessage(errMsg);
        return RestfulResult.fail(e.getCode(), message);
    }

    @ExceptionHandler(RuntimeException.class)
    public RestfulResult<SysException> handlerRuntimeException(RuntimeException e) {
        String errMsg = e.getMessage();
        log.warn("RuntimeException--异常:{}", errMsg);
        return RestfulResult.fail(500, errMsg);
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public RestfulResult<SysException> handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.warn("参数校验异常异常:{}", e.getMessage());
        String msg;
        BindingResult bindingResult = e.getBindingResult();
        FieldError fieldError = bindingResult.getFieldError();
        if (null == fieldError) {
            msg = e.getMessage();
        } else {
            String field = fieldError.getField();
            String defaultMessage = fieldError.getDefaultMessage();
            msg = field + ":" + defaultMessage;
        }
        int code = e.getStatusCode().value();
        return RestfulResult.fail(code, msg);
    }

    @ExceptionHandler(ValidateException.class)
    public RestfulResult<SysException> handlerValidateException(ValidateException e) {
        String errMsg = e.getMessage();
        log.warn("ValidateException--异常:{}", errMsg);
        String message = ResourcesI18n.getMessage(errMsg);
        return RestfulResult.fail(400, message);
    }


    @ExceptionHandler(Exception.class)
    public RestfulResult<SysException> handlerException(Exception e) {
        String errMsg = e.getMessage();
        log.warn("Exception--异常:{}", errMsg);
        return RestfulResult.fail(500, errMsg);
    }


    @ExceptionHandler(AccessDeniedException.class)
    public RestfulResult<SysException> handleAccessDeniedException(AccessDeniedException e) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        if (null == principal) {
            return RestfulResult.fail(401, "请求错误或认证已过期,请重新登录..");
        }
        log.warn("AccessDeniedException--异常:{}", e.getMessage());
        return RestfulResult.fail(403, "没有访问权限");
    }


}
